<template>
  <base-drawer title="查看详情">
    <div class="col" v-loading="detailLoading">
      <base-card class="mb16px style-2" title="角色信息">
        <div class="nowrap items-start lh-22px mb12px">
          <span class="flex-shrink-0 c-[var(--ct3)]">角色名称：</span>
          <span>{{ roleDetail.roleName }}</span>
        </div>
        <div class="nowrap items-start">
          <span class="flex-shrink-0 c-[var(--ct3)]">角色描述：</span>
          <span>{{ roleDetail.roleDesc }}</span>
        </div>
      </base-card>
      <base-card class="mb16px style-2" title="角色信息">
        <div class="nowrap items-start">
          <span class="flex-shrink-0 c-[var(--ct3)]">登录验证：</span>
          <span>{{ roleDetail.isMacCheck === 1 ? "开启" : "关闭" }}</span>
        </div>
      </base-card>
      <base-card class="style-2" title="角色权限">
        <div class="col items-start">
          <span class="flex-shrink-0 c-[var(--ct3)] mb8px">功能权限：</span>
          <base-tree
            v-model="roleDetail.menuIds"
            :data="roleDetail.menuTree"
            node-key="id"
            actions-prop="actions"
            :props="treeProps"
          >
            <template #empty>
              <div class="wfull h500px center">
                <base-empty :image-size="180" description="暂无权限数据" />
              </div>
            </template>
          </base-tree>
        </div>
      </base-card>
    </div>
  </base-drawer>
</template>

<script setup>
  const props = defineProps({
    roleId: {
      type: Number,
      default: 0,
    },
  });

  // 详情加载状态
  const detailLoading = ref(false);

  // 角色详情
  const roleDetail = ref({});

  // 树形属性
  const treeProps = {
    children: "children",
    label: "name",
    disabled: "disabled",
  };

  // 过滤菜单，将 category 为 4 的节点挂载到最近的父节点上
  const filterMenuTree = nodes => {
    if (!nodes || !nodes.length) return [];

    // 将树形结构平铺为一维数组
    const flattenTree = (nodes = []) => {
      return nodes.flatMap(node => {
        // 禁用所有节点
        node.disabled = true;
        // 递归获取子节点
        if (!node.children || node.children.length === 0) return [node];
        // 有子节点，继续递归
        return [node, ...flattenTree(node.children)];
      });
    };

    // 递归处理节点
    return nodes.map(node => {
      const newNode = { ...node };

      // 禁用所有节点
      newNode.disabled = true;

      // 如果没有子节点，直接返回
      if (!newNode.children || newNode.children.length === 0) return newNode;

      const actions = [];
      const regularChildren = [];

      // 遍历子节点，将 category 为 4 的节点收集到 actions 数组中
      newNode.children.forEach(child => {
        // 禁用所有节点
        child.disabled = true;
        // 处理 category === 4
        if (child.category === 4) {
          // 如果子节点是 action，收集它和它的所有后代
          actions.push(child);
          if (child.children && child.children.length > 0) {
            actions.push(...flattenTree(child.children));
          }
        } else {
          // 如果是普通菜单，放入待递归列表
          regularChildren.push(child);
        }
      });

      // 将收集到的 actions 挂载到当前节点
      if (actions.length > 0) {
        newNode.actions = actions;
      }

      // 对普通子节点进行递归处理
      newNode.children = filterMenuTree(regularChildren);

      // 处理完毕，返回新节点
      return newNode;
    });
  };

  // 获取角色详情
  const loadGetRoleDetail = roleId => {
    // 开始加载
    detailLoading.value = true;
    // 获取角色详情
    Api.role
      .GetRoleDetail({ id: roleId })
      .then(res => {
        const data = res.data || {};
        // 过滤菜单树
        data.menuTree = filterMenuTree(data.menuTree || []);
        // 设置角色详情
        roleDetail.value = data || {};
      })
      .finally(() => {
        // 结束加载
        detailLoading.value = false;
      });
  };

  // 获取组件属性
  const attrs = useAttrs();

  // 监听 modelValue 显示状态变化
  watch(
    () => attrs.modelValue,
    open => {
      // 获取角色详情
      if (open) loadGetRoleDetail(props.roleId);
      // 清空角色详情
      else {
        let timer = setTimeout(() => {
          roleDetail.value = {};
          clearTimeout(timer);
          timer = null;
        }, 300);
      }
    },
    { immediate: true }
  );
</script>
<style lang="scss" scoped></style>
